Représentation approximative des nombres réels
Nombre décimaux
Un nombre décimal est un nombre s'écrivant sous la forme $\dfrac{x}{10^{n}}$, où $x$ est un entier relatif.
$\dfrac{13}{4} = \dfrac{325}{100}=\dfrac{325}{10^2}=3,25 = 3,25_{10}$ est un décimal.
$\dfrac{-5}{2}=-2,5=-2,5_{10}$ est un décimal.
$\dfrac{1}{3}=0.3333333...$ n'est pas un décimal. On ne peut pas écrire ce nombre sous la forme $\dfrac{x}{10^{n}}$.
Nombre dyadiques
Par analogie avec les nombres décimaux, on appelle nombres dyadiques les nombres qui s'écrivent sous la forme $\dfrac{x}{2^{n}}$, avec $x$ entier relatif et $n$ entier.
$\dfrac{13}{4}=\dfrac{13}{2^{2}}$ est un nombre dyadique.
$\dfrac{1}{5}=\dfrac{2}{10}$ est un décimal mais pas un nombre dyadique.
Développement dyadique d'un nombre dyadique
On appelle développement dyadique d'un nombre dyadique l'écriture en binaire de ce nombre.
Ce développement dyadique est l'écriture en base 2 d'un nombre dyadique.
Écriture binaire d'un nombre dyadique
Pour obtenir le développement dyadique d'un nombre dyadique $\dfrac{x}{2^{n}}$, on prend le nombre binaire correspondant à $x$ et on insère une virgule avant le $n$-ième bit en partant de la fin.
Écrivons le développement dyadique de $2,5$.
$2,5$ est un nombre dyadique puisque $2,5=\dfrac{5}{2}=\dfrac{5}{2^1}$. Donc on peut écrire son développement dyadique.
On détermine l'écriture en binaire de $5$ :$5_{10}=101_{2}$.
On insère une virgule avant le n-ième bit en partant de la fin.$2,5_{10}=10,1_{2}$.
Écrire le développement dyadique de $31,25$
Cette méthode est fastidieuse parce qu'elle oblige de passer par l'écriture dyadique. De plus que faire des nombres qui ne sont pas dyadiques ?
Partons tout de suite sur un exemple : comment représenter 5,1875 en binaire ?
Il nous faut déjà représenter 5, ça, pas de problème : 101
Comment représenter le ",1875" ?
On multiplie 0,1875 par 2 : 0,1875 x 2 = 0,375. On obtient 0,375 que l'on écrira $\color{red}{0} + \color{blue}{0,375}$.
On multiplie 0,375 par 2 : 0,375 x 2 = 0,75. On obtient 0,75 que l'on écrira $\color{red}{0} + \color{blue}{0,75}$.
On multiplie 0,75 par 2 : 0,75 x 2 = 1,5. On obtient 1,5 que l'on écrira $\color{red}{1} + \color{blue}{0,5}$ (quand le résultat de la multiplication par 2 est supérieur à 1, on garde uniquement la partie décimale).
On multiplie 0,5 par 2 : 0,5 x 2 = 1,0. On obtient 1,0 que l'on écrira $\color{red}{1} + \color{blue}{0,0}$ (la partie décimale est à 0, on arrête le processus).
On obtient une succession de "$\color{red}{a} + \color{blue}{0,b}$" où $a=0$ ou $a=1$ avec :
"$\color{red}{0} + \color{blue}{0,375}$",
"$\color{red}{0} + \color{blue}{0,75}$",
"$\color{red}{1} + \color{blue}{0,5}$" et
"$\color{red}{1} + \color{blue}{0,0}$".
Il suffit maintenant de "prendre" tous les "$\color{red}{0/1}$" (dans l'ordre de leur obtention) afin d'obtenir la partie décimale de notre nombre : $\color{red}{0011}$
Nous avons $101,0011_{2}$ qui est la représentation binaire de $(5,1875)_{10}$.
Trouvez la représentation binaire de :
$4,125_{10}$.
$7,09375_{10}$.
$13,325_{10}$.
Il est possible de retrouver une représentation décimale en base 10 à partir d'une représentation en binaire.
Partons de $(100,0101)_2$.
Pas de problème pour la partie entière, nous obtenons "4".
Pour la partie décimale nous devons écrire : $0 \times 2^{-1} + 1 \times 2^{-2} + 0 \times 2^{-3} + 1 \times 2^{-4}$ $=\dfrac{1}{2^2}+\dfrac{1}{2^4}$ $=\dfrac{1}{4}+\dfrac{1}{16}$ $=0,25+0,0625$ $= 0,3125$.
Nous avons donc $4,3125_{10}$.
Trouvez la représentation décimale de : $100,001_{2}$.
En base dix, il est possible d'écrire les très grands nombres et les très petits nombres grâce aux "puissances de dix" (exemples 6,02.1023 ou 6,67.10-11).
Il est possible de faire exactement la même chose avec une représentation
binaire, puisque nous sommes en base 2, nous utiliserons des "puissances de deux" à la place des "puissances dix" (exemple 101,01001101.2101, où l'exposant est aussi un nombre écrit en binaire.
Pour passer d'une écriture sans "puissance de deux" à une écriture avec "puissance de deux", il suffit décaler la virgule : 1101,1001 = 1,1011001.211 pour passer de "1101,1001" à "1,1011001" nous avons décalé la virgule de 3 rangs vers la gauche d'où le "211" (attention de ne pas oublier que nous travaillons en base 2 le "11" correspond bien à un décalage de 3 rangs de la virgule, car (11) 2=(3)10).
1,1011001 est appelé la mantisse. C'est toujours un nombre compris entre 1 et 2.
11 est appelé l'exposant.
Si l'on désire décaler la virgule vers la gauche, il va être nécessaire d'utiliser des "puissances de deux négatives" 0,0110 = 1,10.2-10, nous décalons la virgule de 2 rangs vers la droite, d'où le "-10".
Pour compléter ce cours, vous pouvez faire une recherche sur le norme IEEE-754 qui n'est pas au programme.
Cette norme définit le codage sur 64 bits des nombres à virgule flottante sous la forme $s\ m\ 2^{n}$, où les lettres $s$, $m$ et $n$n correspondent aux trois informations :
un signe $s$ : un bit est réservé. Il vaut 0 pour le signe "-" et 1 pour le signe "+".
un exposant "décalé" $e$ codé sur 11 bits qui vaut $n+1023$ afin que $e$ soit toujours un nombre positif même si l'exposant $n$ est négatif.
une mantisse tronquée $m-1$ sur 52 bits avec $m$ compris entre 1 et 2 pour coder les 52 premiers bits de la partie fractionnaire de $m$.
Trouvez la représentation binaire de : (0,1)10.
Que remarquez-vous ?
Il existe des nombres décimaux qui ne sont pas dyadiques. Ils n'acceptent pas de développement dyadique fini. Par conséquent leur représentation machine sera nécessairement tronquée. Cela engendrera des erreurs dans les opérations.
Il existe une anecdote illustrant ce problème:
Il ne faudrait surtout pas croire que ces petites erreurs de calcul et d’arrondi soient négligeables, et l’anecdote suivante devrait vous convaincre de l’importance qu’il y a à en prendre conscience.
Le 25 février 1991, à Dharan en Arabie Saoudite, un
missile Patriot américain a raté l’interception d’un missile Scud irakien, ce dernier provoquant la mort de 28 personnes.
La commission d’enquête chargée de comprendre la raison de cet échec a mis en évidence le défaut suivant : L’horloge
interne du missile Patriot mesure le temps en 1/10s.
Pour obtenir le temps en seconde, le système multiplie ce nombre par 10 en utilisant un registre de 24 bits en virgule fixe. Or 1/10 n’est pas un nombre dyadique donc a été arrondi :
le registre de 24 bits contient `0,00011001100110011001100_2` et induit une erreur binaire de `0,0000000000000000000000011001100..._2`, soit approximativement 0,000000095 en notation décimale.
En multipliant cette quantité par le nombre
de 1/10s pendant 100h (le temps écoulé entre la mise en marche du système et le lancement du missile Patriot), on obtient le décalage entre
l’horloge interne de missile et le temps réel, soit : 0,000000095 × 100 × 3600 × 10 ≈ 0,34s.
Or, un missile Scud vole à la vitesse approximative de 1,676m/s donc parcourt plus de 500m en 0,34s, ce qui le fait largement sortir de la zone d’acquisition de sa cible par le missile d’interception.
Cette anecdote est tirée d'un site intéressant : catastrophes numériques
Quelle valeur prend le booléen 0.1+0.2 == 0.3
.
Est-ce cohérent avec vos connaissances en mathématiques ?
Déterminer la représentation binaire de $(0.1)_{10}$.
Déterminer la représentation binaire de $(0.2)_{10}$.
Expliquer pourquoi en informatique $0.1+0.2\neq 0.3$.
Vérifier la valeur approchée affichée pour $0.1+0.2$.
Outre les erreurs de précision liée à la troncature de l'écriture binaire, il peut apparaître d'autres problèmes liés à la représentation des flottants :
Des additions d'"entiers" fausses si l'écart de valeur est important :
9876543210987652.0+1.0
prend la valeur
9876543210987652.0
au lieu de celle
mathématique attendue 9876543210987653.0
.
Des additions non "commutatives" :
1.0 + 1.0 + 9876543210987652.0
prend bien la valeur
9876543210987654.0
mais 9876543210987652.0 + 1.0 + 1.0
prend celle
erronée et différente 9876543210987652.0
.
Écrire en premier lieu une fonction decbin(n)
qui à un entier n renvoie sa décomposition en binaire sous forme de liste.
Écrire en python une fonction deci_en_bin(n)
qui a un nombre décimal n
renvoie son écriture binaire sur 24 bits sous la forme d'une liste. La virgule sera une chaine de caractère.
Écrire une fonction bindec(l)
qui a une liste de correspondant à l'écriture en binaire d'un nombre renvoie le nombre codé en décimal.
Écrire une fonction recherche_de_position(l)
qui a une liste de longueur 24 renvoie la position du caractère ,
ou True
si le caractère n'est pas présent.
Écrire en python une fonction bin_en_deci(l)
qui a un nombre en binaire l
écrit sur 24 bits sous la forme d'une liste renvoie le décimal en base 10 correspondant.
Écrire le développement dyadique de $\dfrac{201}{16}$, c'est-à-dire de $12,5625$.
Les différents
auteurs mettent l'ensemble du site à disposition selon les termes de la licence Creative
Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0
International